package yl.hs.bmipfull.controllers.home;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import yl.hs.bmipfull.controllers.ControllerBase;
import yl.hs.bmipfull.daos.production.IBrickShipOrderDetailDao;
import yl.hs.bmipfull.service.material.IPurchaseReceiptService;
import yl.hs.bmipfull.service.material.IRMTransferService;
import yl.hs.bmipfull.service.production.*;
import yl.hs.bmipfull.service.salemanage.ISaleOrderPlaceService;
import yl.hs.bmipfull.service.salemanage.ISaleOrderService;
import yl.hs.bmipfull.service.system.*;
import yl.hs.bmipfull.service.vehiclemanage.ITruckInfoService;
import yl.hs.bmipfull.utils.CK;
import yl.hs.bmipfull.utils.HsApp;
import yl.hs.bmipfull.utils.Tl;
import yl.hs.bmipfull.viewmodels.WebResult;
import yl.hs.bmipfull.viewmodels.WeightApp.*;

import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.util.*;

/*
 * WeightController
 * @category
 * @author 谢景广
 * @date 2022-04-12
 */
@Slf4j
@Api(value = "无人磅房数据接口", tags = "无人磅房系统——数据操作")
@RequestMapping("/HSApi")
@RestController
public class WeightController extends ControllerBase {
    @Autowired
    ISaleOrderPlaceService placeService;
    @Autowired
    IBrickShipService brickOrderService;
    @Autowired
    IBrickShipOrderDetailDao brickShipOrderDetailDao;
    @Autowired
    IWechatUserService wxUser;

    @ApiOperation(value = "获取地磅配置信息", notes = "无人磅房系统—— 获取地磅配置信息")
    @RequestMapping(value = "DownloadConfig", method = RequestMethod.GET)
    @ResponseBody
    public WeightResult<Object> downloadConfig(String SNO) {
        if (Tl.isEmpty(SNO)) {
            return new WeightResult<>(false, "非法访问");
        } else {
            var db = service.findBySn(SNO);
            if (db != null) {
                var config = new DeviceInfo();
                var wee = new SerialPortDevice();
                wee.setDeviceName(db.getDeviceName());
                wee.setBaudRate(db.getBaudRate());
                wee.setPortName(db.getPortName());
                wee.setReverse(db.getisReverse());
                wee.setEnabled(db.getEnableMark());
                wee.setDataBits(db.getDataBits());
                wee.setStartIndex(db.getStartIndex());
                wee.setDataLenght(db.getDataLength());
                wee.setStopBit(db.getStopBits());
                wee.setParity(db.getParity());
                wee.setWeighModel(db.getWeighModel());
                wee.setDataUnit(db.getDataUnit());
                config.setWeighbridge(wee);
                config.setEnabled(db.getEnableMark());
                config.setDeviceName(db.getDeviceName());
                //config.setWeighbridge(new SerialPortDevice());
                var netList = netSvc.queryListByDBSn(db.getSn());
                if (netList.size() > 0) {
                    var carmaList = netList.stream().filter(t -> "监控".equals(t.getDeviceType())).toList();
                    if (carmaList.size() > 0) {
                        var cList = new ArrayList<NetworkDevice>();
                        for (var item : carmaList) {
                            var c = new NetworkDevice();
                            c.setDataLenght(item.getDataLength());
                            c.setDeviceName(item.getDeviceName());
                            c.setEnabled(item.getEnableMark());
                            c.setDevicePort(item.getIPProt());
                            c.setLoginName(item.getLoginName());
                            c.setPassword(item.getLoginPwd());
                            c.setLocation(item.getDeviceLocation());
                            c.setServer(item.getIsServer());
                            c.setStartIndex(item.getStartIndex());
                            c.setiPAddress(item.getiPAddress());
                            cList.add(c);
                        }
                        config.setCameras(cList);
                    }
                    var tPlate = netList.stream().filter(t -> "车牌识别".equals(t.getDeviceType())).toList();

                    if (tPlate.size() > 0) {
                        for (var tData : tPlate) {
                            var plate = new NetworkDevice();
                            plate.setiPAddress(tData.getiPAddress());
                            plate.setLocation(tData.getDeviceLocation());
                            plate.setDevicePort(tData.getIPProt());
                            plate.setLoginName(tData.getLoginName());
                            plate.setPassword(tData.getLoginPwd());
                            plate.setEnabled(tData.getEnableMark());
                            plate.setDeviceName(tData.getDeviceName());

                            config.addTruckPlateRecognitions(plate);
                        }
                    }
                    var integratedOpt = netList.stream().filter(t -> "红外光栅".equals(t.getDeviceType())).findFirst();
                    if (integratedOpt.isPresent()) {
                        var iData = integratedOpt.get();
                        var iObj = new NetworkDevice();
                        iObj.setDeviceName(iData.getDeviceName());
                        iObj.setLocation(iData.getDeviceLocation());
                        iObj.setiPAddress(iData.getiPAddress());
                        iObj.setEnabled(iData.getEnableMark());
                        iObj.setDevicePort(iData.getIPProt());
                        config.setIntegrated(iObj);
                    }
                    var nsOpt = netList.stream().filter(t -> "二维码扫描仪".equals(t.getDeviceType())).toList();
                    if (nsOpt.size() > 0) {
                        for (var item : nsOpt) {
                            if (item.getDeviceName().equals("udp语音")) {
                                var nsObj = new NetworkDevice();
                                nsObj.setDevicePort(item.getIPProt());
                                nsObj.setEnabled(item.getEnableMark());
                                nsObj.setLocation(item.getDeviceLocation());
                                nsObj.setPassword(item.getLoginPwd());
                                nsObj.setLoginName(item.getLoginName());
                                nsObj.setServer(item.isServer());
                                nsObj.setDataLenght(item.getDataLength());
                                nsObj.setStartIndex(item.getStartIndex());
                                nsObj.setiPAddress(item.getiPAddress());
                                nsObj.setDeviceName(item.getDeviceName());
                                config.addNetScanner(nsObj);
                            } else {
                                var nsObj = new NetworkDevice();
                                nsObj.setDevicePort(item.getIPProt());
                                nsObj.setEnabled(item.getEnableMark());
                                nsObj.setLocation(item.getDeviceLocation());
                                nsObj.setPassword(item.getLoginPwd());
                                nsObj.setLoginName(item.getLoginName());
                                nsObj.setServer(item.isServer());
                                nsObj.setDataLenght(item.getDataLength());
                                nsObj.setStartIndex(item.getStartIndex());
                                nsObj.setiPAddress(item.getiPAddress());
                                nsObj.setDeviceName(item.getDeviceName());
                                config.addNetScannerQR(nsObj);
                            }
                        }
                    }
                }
                var serList = serSvc.queryListByDBSn(db.getSn());
                if (serList.size() > 0) {
                    var crOpt = serList.stream().filter(t -> "蓝牙读卡器".equals(t.getDeviceType())).findFirst();
                    if (crOpt.isPresent()) {
                        var crData = crOpt.get();
                        var crObj = new SerialPortDevice();
                        crObj.setDeviceName(crData.getDeviceName());
                        crObj.setPortName(crData.getPortName());
                        crObj.setBaudRate(crData.getBaudRate());
                        crObj.setDataBits(crData.getDataBits());
                        crObj.setParity(crData.getParity());
                        crObj.setStopBit(crData.getStopBits());
                        crObj.setEnabled(crData.getEnableMark());
                        crObj.setStartIndex(crData.getStartIndex());
                        crObj.setDataLenght(crData.getDataLength());
                        config.setCardReader(crObj);
                    }
                    var ssOpt = serList.stream().filter(t -> "二维码扫描仪".equals(t.getDeviceType())).findFirst();
                    if (ssOpt.isPresent()) {
                        var ssData = ssOpt.get();
                        var ssObj = new SerialPortDevice();
                        ssObj.setDeviceName(ssData.getDeviceName());
                        ssObj.setPortName(ssData.getPortName());
                        ssObj.setBaudRate(ssData.getBaudRate());
                        ssObj.setDataBits(ssData.getDataBits());
                        ssObj.setParity(ssData.getParity());
                        ssObj.setStopBit(ssData.getStopBits());
                        ssObj.setStartIndex(ssData.getStartIndex());
                        ssObj.setDataLenght(ssData.getDataLength());
                        ssObj.setEnabled(ssData.getEnableMark());
                        config.setSerScanner(ssObj);
                    }
                }
                return new WeightResult<>(true, "OK", config);
            } else {
                return new WeightResult<>(false, "无效的地磅编号");
            }
        }
    }

    @ApiOperation(value = "车辆验证", notes = "无人磅房系统——车辆验证")
    @RequestMapping(value = "CheckCar", method = RequestMethod.GET)
    @ResponseBody
    public WeightResult<Object> checkCar(@ApiParam(required = true, name = "车牌号或者卡号") String Truck, String DBSNO) {
        try {
            var logBuilder = new StringBuilder(Truck);
            var result = new HashMap<String, Object>();
            logBuilder.append("\t");
            var cp = brickOrderService.findByTruckPlate(Truck, 0);
            var yc = receiptSvc.queryByTruckPlateByState(Truck);
            if (cp != null) {
                var truckplates = placeService.findByTruckPlate(Truck, 4);
                result.put("HandlerType", true);
                if (truckplates == null) {
                    return new WeightResult<>(false, "车辆未出库，请联系库管", result);
                }
                result.put("WeighType", true);
                result.put("CarFrom", 1);
                result.put("IsWeigh", true);
                return new WeightResult<>(true, "验证成功！", result);
            } else if (yc != null) {
                result.put("HandlerType", false);
                result.put("WeighType", true);
                result.put("CarFrom", 1);
                result.put("IsWeigh", true);
                if (yc.getCheckState() == 0) {
                    return new WeightResult<>(false, "未质检，不允许过磅", result);
                }
                return new WeightResult<>(true, "验证成功！", result);
            }
            var wxuserentity = wxUser.findByTruckPlate(Truck, 0);
            if (wxuserentity == null) {
                var truckplate = placeService.findByTruckPlate(Truck, 3);
                var truckplates = placeService.findByTruckPlate(Truck, 4);
                if (truckplate != null || truckplates != null) {
                    result.put("HandlerType", true);
                    var intruck = brickOrderService.findByTruckPlate(Truck, 0);
                    if (intruck != null) {
                        if (truckplates == null) {
                            return new WeightResult<>(false, "车辆未出库，请联系库管", result);
                        }
                        result.put("WeighType", true);
                        result.put("CarFrom", 1);
                        result.put("IsWeigh", true);
                    } else {
                        if (truckplate == null && truckplates != null) {
                            return new WeightResult<>(false, "请先暂存车辆", result);
                        }
                        var truck = truckplate == null ? truckplates : truckplate;
                        var detail = placeService.queryDetailBySn(truck.getSn());
                        var ss = truck.toMap();
                        ss.put("detail", detail);
                        result.put("WeighType", false);
                        result.put("CarFrom", 1);
                        result.put("IsWeigh", true);
                        result.put("order", ss);
                    }
                    return new WeightResult<>(true, "验证成功！", result);
                }
            } else {
                result.put("HandlerType", false);
                result.put("WeighType", false);
                result.put("CarFrom", 1);
                result.put("IsWeigh", true);
                log.info("车辆检测：" + logBuilder.toString());
                return new WeightResult<>(true, "验证成功！", result);
            }
            return new WeightResult<>(false, "未授权");
        } catch (Exception ee) {
            log.error(this.getClass() + "-CheckCar", ee);
            return new WeightResult<>(false, ee.getMessage());
        }
    }

    @ApiOperation(value = "保存称重", notes = "无人磅房系统——保存称重")
    @RequestMapping(value = "TransWeight", method = RequestMethod.POST)
    @ResponseBody
    public WeightResult<Object> saveWeight(@ApiParam(value = "查询条件") @RequestBody Map<String, Object> data) {
        var truckNum = data.get("Truck");
        var dbSno = Tl.getString(data.get("DBSNO"));
        if (truckNum != null && !"".equals(truckNum)) {
            var weight = Tl.getBigDecimal(data.get("Weight"));
            var discern = Tl.getString(data.get("Discern"));
            var handlerType = Tl.getBool(data.get("HandlerType"), true);
            var weighType = Tl.getBool(data.get("WeighType"), true);
            var orgWeight = Tl.getBigDecimal(data.get("OrgWeight"));
            var handler = Tl.getString(data.get("handlerName"));
            var carname = Tl.getString(data.get("equipmentCode"));
            var stationType = Tl.getString(data.get("stationType"));
            if (weight.compareTo(BigDecimal.ZERO) <= 0) {
                return new WeightResult<>(false, "称重信息必须大于0！");
            }
            try {
                var result = weightSvc.Save(dbSno, weight, discern, handlerType, weighType, orgWeight, handler, carname, stationType, truckNum.toString());
                if (result.getSaveResult() <= 0) {
                    return new WeightResult<>(false, result.getMessage(), result.getSaveResult());
                } else {
                    var rspData = new HashMap<String, Object>();
                    if (weighType) {
                        var orderData = new HashMap<String, Object>();
                        switch (result.getOrderType()) {
                            case 0: //原材入库
                                var rawOrder = receiptSvc.findBySn(result.getOrderSNO());
                                orderData.put("Master", rawOrder);
                                break;
                            case 1: //商砼发货
                                var brickorder = brickOrderService.findBySN(result.getOrderSNO());
                                var maps = brickorder.toMap();
                                maps.put("detail", brickShipOrderDetailDao.getListByOrderSN(brickorder.getSn()));
                                orderData.put("Master", maps);
                                break;
                            case 2://砂浆发货
                                var order = orderSvc.findBySn(result.getOrderSNO());
                                var task = taskService.findBySn(order.getTaskSN());
                                var map = order.toMap();
                                map.put("projectLinker", task.getProjectLinker());
                                map.put("projectPhone", task.getProjectPhone());
                                orderData.put("Master", map);
                                break;
                            //水稳发货 3, 沥青发货 4,原材发货 5
                            case 3, 4, 5, 6:
                                orderData.put("Master", orderSvc.findBySn(result.getOrderSNO()));
                                break;
                        }
                        rspData.put("OrderType", result.getOrderType());
                        rspData.put("OrderID", result.getOrderSNO());
                        rspData.put("orderData", orderData);
                        return new WeightResult<>(true, "上传完成", rspData);
                    } else {
                        rspData.put("OrderType", result.getOrderType());
                        rspData.put("OrderID", result.getOrderSNO());
                    }
                    rspData.put("OrderType", result.getOrderType());
                    rspData.put("OrderID", result.getOrderSNO());
                    return new WeightResult<>(true, "上传完成", rspData);
                }
            } catch (Exception ee) {
                log.error(this.getClass() + "-saveWeight", ee);
                return new WeightResult<>(false, ee.getMessage());
            }
        }
        return new WeightResult<>();
    }

    @ApiOperation(value = "更新打印次数", notes = "无人磅房系统——更新打印次数")
    @RequestMapping(value = "UpPrint", method = RequestMethod.GET)
    @ResponseBody
    public WeightResult<String> upPrint(int OrderType, String OrderID) {
        try {
            weightSvc.appendOrderPrintCount(OrderType, OrderID);
            return new WeightResult<>(true, "修改成功");
        } catch (Exception ee) {
            log.error(this.getClass() + "-upPrint", ee);
            return new WeightResult<>(false, ee.getMessage());
        }
    }

    @ApiOperation(value = "上传监控拍照图片", notes = "无人磅房系统——上传图片")
    @RequestMapping(value = "UpLoadPic", method = RequestMethod.POST)
    @ResponseBody
    public WeightResult upLoadPic(@RequestBody PhotoPicModer model) {
        try {
            if (Tl.isEmpty(HsApp.getSystemSet(CK.UpLoadFilePath))) {
                var root = orgSvc.findRootUnit();
                if (root != null) {
                    setSvc.querySetObjByUnitSn(new String[]{root.getSn()});
                }
            }
            var filePath = HsApp.getSystemSet(CK.UpLoadFilePath);
            assert filePath != null;
            File folder = new File(filePath);
            if (!folder.exists() || !folder.isDirectory()) {
                folder.mkdir();
            }
            FileOutputStream fos = new FileOutputStream(filePath + File.separator + model.getFileName());
            byte[] decoded = Base64.getDecoder().decode(model.getFileData());
            fos.write(decoded);
            fos.flush();
            fos.close();
            return new WeightResult<>(true, "上传成功", true);
        } catch (Exception ee) {
            log.error(this.getClass() + "-upLoadPic", ee);
            return new WeightResult<>(false, ee.getMessage(), false);
        }
    }

    @ApiOperation(value = "蓝牙读卡器回厂", notes = "无人磅房系统——蓝牙读卡器回厂")
    @RequestMapping(value = "BetonCarBack", method = RequestMethod.GET)
    @ResponseBody
    public WeightResult<String> BackCarNum(@ApiParam(required = true, name = "车牌号或者卡号") String cardnum) {
        try {
            var car = truckInfoService.findByCardSn(cardnum);
            if (car != null) {
                car.setEquipmentCode("常春藤");
                var result = truckInfoService.truckBack(car);
                if (result) {
                    return new WeightResult<>(true, car.getTruckCode() + "-蓝牙卡回厂");
                }
            }
        } catch (Exception ee) {
            log.error(this.getClass() + "-BackCarNum", ee);
            return new WeightResult<>(false, ee.toString());
        }
        return new WeightResult<>(false, "回皮失败");
    }

    @ApiOperation(value = "查询是否有成品发货车辆", notes = "无人磅房系统——查询是否有成品发货车辆")
    @RequestMapping(value = "getOrderPc/{truckPlate}", method = RequestMethod.GET)
    @ResponseBody
    public WebResult getOrderPc(@PathVariable String truckPlate) {
        var result = placeService.querylistByState(truckPlate);
        if (Objects.equals(result.toString(), "2")) {
            return success("请前往门岗北侧西第一个窗口咨询", result);
        } else if (Objects.equals(result.toString(), "3")) {
            return success("请与业务员或客户联系");
        } else {
            return success("车辆已登记请耐心排队等待",result);
        }
    }

    @ApiOperation(value = "判断原材车辆是否注册", notes = "无人磅房系统——判断原材车辆是否注册")
    @RequestMapping(value = "getrmtruckorder/{truckPlate}", method = RequestMethod.GET)
    @ResponseBody
    public WebResult getRmTruckOrder(@PathVariable String truckPlate) {
        var truck = truckInfoService.findByTruck(truckPlate);
        if (truck != null) {
            var wxuserentity = wxUser.findByOpenId(truck.getOpenId());
            if (wxuserentity != null) {
                if (Tl.isEmpty(wxuserentity.getRmSN()) || Tl.isEmpty(wxuserentity.getPurchaseContractSN()) || Tl.isEmpty(wxuserentity.getRmCateSN())) {
                    return success("无注册信息");
                } else {
                    return success("车辆已登记请耐心排队等待", wxuserentity);
                }
            } else {
                return success("无注册信息");
            }
        } else {
            return success("无注册信息");
        }
    }

    IRMTransferService rmTransSvc;

    @Autowired
    public void setRmTransSvc(IRMTransferService rmTransSvc) {
        this.rmTransSvc = rmTransSvc;
    }

    IWeighingEquipmentService service;

    @Autowired
    public void setService(IWeighingEquipmentService service) {
        this.service = service;
    }

    IWHNetEquipmentService netSvc;

    @Autowired
    public void setNetSvc(IWHNetEquipmentService netSvc) {
        this.netSvc = netSvc;
    }

    IWHSerEquipmentService serSvc;

    @Autowired
    public void setSerSvc(IWHSerEquipmentService serSvc) {
        this.serSvc = serSvc;
    }
    IProductShipOrderService orderSvc;

    @Autowired
    public void setOrderSvc(IProductShipOrderService orderSvc) {
        this.orderSvc = orderSvc;
    }

    IPurchaseReceiptService receiptSvc;

    @Autowired
    public void setReceiptSvc(IPurchaseReceiptService receiptSvc) {
        this.receiptSvc = receiptSvc;
    }

    IWeightService weightSvc;

    @Autowired
    public void setWeightSvc(IWeightService weightSvc) {
        this.weightSvc = weightSvc;
    }

    IProductionTaskService taskService;

    @Autowired
    public void setTaskService(IProductionTaskService taskService) {
        this.taskService = taskService;
    }

    IAppSettingService setSvc;

    @Autowired
    public void setSetSvc(IAppSettingService setSvc) {
        this.setSvc = setSvc;
    }

    ITransTaskService tranService;

    @Autowired
    public void setTranService(ITransTaskService tranService) {
        this.tranService = tranService;
    }

    IOrganizationInfoService orgSvc;

    @Autowired
    public void setOrgSvc(IOrganizationInfoService orgSvc) {
        this.orgSvc = orgSvc;
    }

    IWechatUserService wechatUserService;

    @Autowired
    public void setWechatUserService(IWechatUserService wechatUserService) {
        this.wechatUserService = wechatUserService;
    }

    IProductShipOrderService productShip;

    @Autowired
    public void setProductShip(IProductShipOrderService productShip) {
        this.productShip = productShip;
    }
    ITruckInfoService truckInfoService;
    @Autowired
    public void setTruckInfoService(ITruckInfoService truckInfoService) {
        this.truckInfoService = truckInfoService;
    }
}
